package com.mango.config;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.mango.downloader.PRDownloader;
import com.mango.downloader.PRDownloaderConfig;
import com.mango.imageloader.core.ImageLoader;
import com.mango.imageloader.core.ImageLoaderConfiguration;
import com.mango.oaid.DeviceIdentifier;
import com.mango.request.Algorithm;
import com.mango.request.ReqMgConfig;
import com.mango.request.beans.ConfigBean;
import com.mango.volley.RequestQueue;
import com.mango.volley.toolbox.RequestFuture;
import com.mango.volley.toolbox.Volley;
import com.mango.wall.BuildConfig;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public final class BaseWall implements Application.ActivityLifecycleCallbacks {
    private static volatile BaseWall mInstance;

    public static BaseWall getInstance() {
        if (mInstance == null) {
            synchronized (BaseWall.class) {
                if (mInstance == null)
                    mInstance = new BaseWall();
            }
        }
        return mInstance;
    }

    private Application mApp;
    private String mAppID, mAppKey;

    private RequestQueue mRequestQueue;
    private ImageLoaderConfiguration mImageLoaderConfiguration;

    private Thread mConfigThread;
    private ConfigBean mConfigBean;

    @SuppressWarnings("ResultOfMethodCallIgnored")
    public synchronized void init(Application app, String appID, String appKey) {
        if (mConfigThread != null || mConfigBean != null) return;
        app.registerActivityLifecycleCallbacks(this);

        mApp = app;
        mAppID = appID;
        mAppKey = appKey;

        DeviceIdentifier.register(mApp);
        mRequestQueue = Volley.newRequestQueue(mApp);
        mImageLoaderConfiguration = ImageLoaderConfiguration.createDefault(mApp);
        PRDownloader.initialize(mApp, PRDownloaderConfig.newBuilder().setDatabaseEnabled(true).build());

        mConfigThread = new Thread() {
            @Override
            public void run() {
                // 请求配置信息
                RequestFuture<ConfigBean> future = RequestFuture.newFuture();
                mRequestQueue.add(new ReqMgConfig(mAppID, mAppKey, future, future));

                // 读取缓存配置
                File category = new File(mApp.getFilesDir(), "ManGo");
                File configFile = new File(category, Algorithm.MD5Encrypt(
                        mAppID + mAppKey).toUpperCase());
                category.mkdirs();

                try {
                    FileInputStream fis = new FileInputStream(configFile);
                    ObjectInputStream ois = new ObjectInputStream(fis);
                    mConfigBean = (ConfigBean) ois.readObject();
                    ois.close();
                    if (BuildConfig.DEBUG)
                        Log.d("ManGo", "读取缓存配置成功");
                } catch (Exception exception) {
                    if (BuildConfig.DEBUG)
                        Log.e("ManGo", "读取缓存配置失败", exception);
                }

                // 更新缓存配置
                while (true) {
                    try {
                        mConfigBean = future.get();
                        configFile.delete();

                        FileOutputStream fos = new FileOutputStream(configFile);
                        ObjectOutputStream oos = new ObjectOutputStream(fos);
                        oos.writeObject(mConfigBean);
                        oos.close();
                    } catch (Exception exception) {
                        if (BuildConfig.DEBUG)
                            Log.e("ManGo", "更新缓存配置失败", exception);
                    }

                    if (mConfigBean != null) break;

                    sleep();
                    future = RequestFuture.newFuture();
                    mRequestQueue.add(new ReqMgConfig(mAppID, mAppKey, future, future));
                }
            }

            private void sleep() {
                try {
                    Thread.sleep(3000);
                } catch (Exception exception2) {
                    // Do nothing.
                }
            }
        };
        mConfigThread.start();
    }

    public Application getApplication() {
        return mApp;
    }

    public String getAppID() {
        return mAppID;
    }

    public String getAppKey() {
        return mAppKey;
    }

    public ConfigBean getConfig() {
        return mConfigBean;
    }

    public RequestQueue getQueue() {
        return mRequestQueue;
    }

    public ImageLoader getImageLoader() {
        if (!ImageLoader.getInstance().isInited())
            ImageLoader.getInstance().init(mImageLoaderConfiguration);
        return ImageLoader.getInstance();
    }

    @Override
    public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
    }

    @Override
    public void onActivityStarted(@NonNull Activity activity) {
    }

    @Override
    public void onActivityResumed(@NonNull Activity activity) {
    }

    @Override
    public void onActivityPaused(@NonNull Activity activity) {
    }

    @Override
    public void onActivityStopped(@NonNull Activity activity) {
    }

    @Override
    public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
    }

    @Override
    public void onActivityDestroyed(@NonNull Activity activity) {
    }
}
